
#ifndef UNITY_SHADER_DT_EFFECT_TOOLS_UTIL_INCLUDED
#define UNITY_SHADER_DT_EFFECT_TOOLS_UTIL_INCLUDED

    
    //计划 
    // 0. Fx通用模块 ===>通用函数，尽量精简内容，非必要比加入的内容
    // 1. UV
    // 2. 颜色
    // 3. 遮罩
    // 4. 扰动/扭曲
    // 5. 溶解

    // 通用模块
    // UNITY_SHADER_DT_FX_COMMON_UTIL_INCLUDED
    // COLOR BLEND 模块
    // UNITY_SHADER_DT_COLORBLEND_UTIL_INCLUDED
    // UV 模块
    // UNITY_SHADER_DT_UV_UTIL_INCLUDED
    // 颜色 模块
    // UNITY_SHADER_DT_COLOR_UTIL_INCLUDED 
    // MASK 遮罩
    // UNITY_SHADER_DT_MASK_UTIL_INCLUDED
    // DISTORT 扰动
    // UNITY_SHADER_DT_DISTORT_UTIL_INCLUDED
    // DISSOLVE 溶解
    // UNITY_SHADER_DT_DISSOLVE_UTIL_INCLUDED
    // FNL 菲尼尔
    // UNITY_SHADER_DT_FNL_UTIL_INCLUDED    
    // GROUND 地面裁切模拟
    // UNITY_SHADER_DT_GROUND_UTIL_INCLUDED  
   
    
// ======================================================================================================================================================================================================
//
//
//
//
// 引用的文件
//
//
//
//
// ======================================================================================================================================================================================================
        #ifdef DT_URP_MODE
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"   
        #else
            #include "UnityCG.cginc"
        #endif  
// ======================================================================================================================================================================================================
//
//
//
//
//
//
//
// Fx通用模块
//
//
//
//
//
//
//
// ======================================================================================================================================================================================================
    #ifndef UNITY_SHADER_DT_FX_COMMON_UTIL_INCLUDED  
    #define UNITY_SHADER_DT_FX_COMMON_UTIL_INCLUDED
        // ======================================================================
        // 精度总控制
        // ======================================================================
            typedef float        DTfloat;
            typedef float2       DTfloat2;
            typedef float3       DTfloat3;
            typedef float4       DTfloat4;

            typedef float2x2     DTfloat2x2;
            typedef float2x3     DTfloat2x3;
            typedef float2x4     DTfloat2x4;

            typedef float3x2     DTfloat3x2;
            typedef float3x3     DTfloat3x3;
            typedef float3x4     DTfloat3x4;
            typedef float4x3     DTfloat4x3;
            typedef float4x4     DTfloat4x4;

            #define DT_INV2PI 0.15915494309f //UNITY_INV_TWO_PI
            #define SAFE_MIN 0.0001
            #define SAFE_MIN2 float2(0.0000001,0.0000001)
            #define SAFE_COLOR_MIN 0.003921568627451
            #define SAFE_COLOR_MAX 0.996078431372549
            #define SAFE_FLOAT_MIN -60000
            #define SAFE_FLOAT_MAX 60000

            #define DT_SAFE_VALUE(v) (abs(v) < SAFE_MIN ? SAFE_MIN : (v))
            // #define DT_SAFE_VALUE2(v) (abs(v.xy) < SAFE_MIN2 ? SAFE_MIN2 : (v.xy))
            #define SAFE_COLOR(col) (clamp((col), SAFE_COLOR_MIN, SAFE_COLOR_MAX))


            static const float4 DTFullChannelMask[16] = {
                // R    G    B    A = # # # #
                float4(0, 0, 0, 0), // 0000
                float4(0, 0, 0, 1), // 0001  A通道= index = 1
                float4(0, 0, 1, 0), // 0010  B通道= index = 2
                float4(0, 0, 1, 1), // 0011
                float4(0, 1, 0, 0), // 0100  G通道= index = 4
                float4(0, 1, 0, 1), // 0101
                float4(0, 1, 1, 0), // 0110
                float4(0, 1, 1, 1), // 0111
                float4(1, 0, 0, 0), // 1000  R通道= index = 8
                float4(1, 0, 0, 1), // 1001
                float4(1, 0, 1, 0), // 1010
                float4(1, 0, 1, 1), // 1011
                float4(1, 1, 0, 0), // 1100
                float4(1, 1, 0, 1), // 1101
                float4(1, 1, 1, 0), // 1110
                float4(1, 1, 1, 1)  // 1111
            };
            static const float4 DTOneChannelMask[4] = {
                float4(0, 0, 0, 1),     //A通道= index = 0
                float4(1, 0, 0, 0),     //R通道= index = 1
                float4(0, 1, 0, 0),     //G通道= index = 2
                float4(0, 0, 1, 0)      //B通道= index = 3
            };

            static const float2 DTTowSwichMask[4] = {
                float2(0, 0),     //全关= index = 0
                float2(1, 0),     //单开X= index = 1
                float2(0, 1),     //单开Y= index = 2
                float2(1, 1)      //全开= index = 3
            };

        // ==================================================================
        // 函数
        // ================================================================== 
        float dt_Ramp_float(float val, float IMIN, float IMAX, float OMIN, float OMAX) 
        { 
            return OMIN + ((val - IMIN) * (OMAX - OMIN)) / DT_SAFE_VALUE(IMAX - IMIN);
        }

        float4 DTtex2D (sampler2D _MainTex, float2 uv)
        {
            #ifdef DT_URP_MODE
                return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
            #else
                return tex2D(_MainTex, uv);
            #endif
        }

    #endif //UNITY_SHADER_DT_FX_COMMON_UTIL_INCLUDED
    
// ================================================================================================================================================ 
//
//
//
//
//
//
//
// Color Blend 模块
//
//
//
//
//
//
//
// ================================================================================================================================================

// #include "DTColorBlendUtil.hlsl"
// ============================================================================================================================================
    // ============================================================================================================================================
    //
    //
    // DTColorBlend 颜色混合
    //
    //
    // ============================================================================================================================================
    #ifndef UNITY_SHADER_DT_COLORBLEND_UTIL_INCLUDED  
    #define UNITY_SHADER_DT_COLORBLEND_UTIL_INCLUDED
        
        // [Enum(A,0,R,1,G,2,B,3,L,4)]_####AlphaMode ("#### Use Channel=>Alpha", Float) = 0
        // _####TintColor ("#### Tint Color", Color) = (1,1,1,1)
        // [Enum(None,0,Tinting,1,Multiply,2,Screen,3,Overlay,4,Normal,5)]_####TintBlendMode ("#### Tint Blend Mode", Float) = 0.0
        // _####Brightness ("#### Brightness", Range(0.0,10.0)) = 1.0
        // _####FilterGray ("#### Filter Gray", Range(0.0,1.0)) = 0.0
        // _####FilterInvert ("#### Filter Invert", Range(0.0,1.0)) = 0.0
        
        //==========================================================================================================================================================
        //
        //  Blend PS混合模式
        //  layer0 是下图层
        //  layer1 是上图层
        //
        //==========================================================================================================================================================
            float4 dt_ToInputColor(float4 col)
            {
                #ifdef UNITY_COLORSPACE_GAMMA
                    return col; 
                #else
                    const float INV_GAMMA = 1.0 / 2.2;
                    return pow(col,INV_GAMMA);
                #endif
            }
            float3 dt_ToInputColor3(float3 col)
            {
                #ifdef UNITY_COLORSPACE_GAMMA
                    return col; 
                #else
                    const float INV_GAMMA = 1.0 / 2.2;
                    return pow(col,INV_GAMMA);
                #endif
            }
            //输出结果时,把统一颜色正确输出
            float4 dt_ToOutputColor(float4 color)
            {
                #ifdef UNITY_COLORSPACE_GAMMA
                    return color;
                #else
                    const float GAMMA = 2.2;
                    return pow(color,GAMMA);
                #endif
            }
            float3 dt_ToOutputColor3(float3 color)
            {
                #ifdef UNITY_COLORSPACE_GAMMA
                    return color;
                #else
                    const float GAMMA = 2.2;
                    return pow(color,GAMMA);
                #endif
            }
            // 混合公式的只是颜色，但透明会影响颜色的显示，但不能直接预乘，
            // 因为很多计算使用的是颜色本身，预乘会让颜色变暗，所以最后要处理前层的透明度
            float3 DT_PS_ExpotColorBlendResultColor(float3 finalColor, float3 srcColor, float newLayerAlpha) 
            { 
                return finalColor * newLayerAlpha + srcColor * (1.0 - newLayerAlpha); 
            }

            float3 DT_GetGray(float3 layer0)
            {
                return  (layer0.r + layer0.g + layer0.b) / 3.0; // 最终颜色 
            }            
            float3 DT_GetInvert(float3 layer0)
            {
                return abs(1.0 - layer0); // 最终颜色 
            }
        // ==================================================================
        //
        // 普通
        //
        // ==================================================================
            float3 DT_PS_NORMAL(float3 layer0, float3 layer1)
            {  
                return layer1;
            }
        // ==================================================================
        //
        // 变亮
        //
        // ==================================================================          
            float3 DT_PS_LIGHTEN(float3 layer0, float3 layer1) {
                return max(layer0.rgb, layer1.rgb);
            }
        // ==================================================================
        //
        // 变暗
        //
        // ==================================================================           
            float3 DT_PS_DARKEN(float3 layer0, float3 layer1)
            {
                return min(layer0.rgb, layer1.rgb);
            }
        // ==================================================================
        //
        // 正片叠底
        //
        // ==================================================================            
            float3 DT_PS_MULTIPLY(float3 layer0, float3 layer1)
            {
                return layer1 * layer0;
            }
        // ==================================================================
        //
        // 滤色 1 - (1 - a) * (1 - b)
        //
        // ==================================================================
            float3 DT_PS_SCREEN(float3 layer0, float3 layer1)
            {
                return layer0.rgb + layer1.rgb - layer0.rgb * layer1.rgb;
            } 
        // ==================================================================
        //
        // 颜色加深
        //
        // ================================================================== 
            float3 DT_PS_COLOR_BURN(float3 layer0, float3 layer1)
            {
                float3 col = SAFE_COLOR(layer1); //防除0
                return layer0 - (float3(1.0,1.0,1.0) - layer0) * (float3(1.0,1.0,1.0) - layer1) / col;
            }             
        // ==================================================================
        //
        // 颜色减淡
        //
        // ==================================================================
            float3 DT_PS_COLOR_DODGE(float3 layer0, float3 layer1) {
                return min(1.0, layer0.rgb / (float3(1.0,1.0,1.0) - layer1.rgb));
            }
        // ==================================================================
        //
        // 经典颜色减淡
        //
        // ==================================================================
            float3 DT_PS_CLASSIC_COLOR_DODGE(float3 layer0, float3 layer1)
            {
                const float3 a = layer0.rgb;
                const float3 b = layer1.rgb;
                const float3 col = SAFE_COLOR((float3(1.0,1.0,1.0) - a.rgb)); //防除0
                return b.xyz + a.xyz * layer1.xyz / col.xyz;
            } 
        // ==================================================================
        //
        // 线性加深
        //
        // ==================================================================     
            float3 DT_PS_LINEAR_BURN(float3 layer0, float4 layer1) {
                return layer0.rgb + layer1.rgb - float3(1.0,1.0,1.0);
            }
        // ==================================================================
        //
        // 相加 // 线性减淡
        //
        // ==================================================================    
            float3 DT_PS_ADD(float3 layer0, float3 layer1) {
                return layer1.rgb + layer0.rgb;
            }
        // ==================================================================
        //
        // 叠加
        //
        // ==================================================================
            float3 DT_PS_OVERLAY(float3 _layer0, float3 _layer1)
            { 
                float3 vblack = 2.0 * _layer0 * _layer1;  
                float3 vlinght = 1.0 -  2.0 * (1.0 - _layer0) * (1.0 - _layer1);   
                float3 resultColor = 1;
                float l = 0.01;float l1 = 0.5 - l;  float l2 = 0.5 + l; 
                resultColor.r = smoothstep(l1, l2, _layer0.r);
                resultColor.g = smoothstep(l1, l2, _layer0.g);
                resultColor.b = smoothstep(l1, l2, _layer0.b); 
                float3 finalColor = lerp(vblack, vlinght, resultColor); 
                // float3 finalColor = vblack * (1.0 - resultColor) + vlinght * resultColor  ; 
                return saturate(finalColor ); 
            }
        // ==================================================================
        //
        // 着色
        //
        // ==================================================================
            float getLuminance(float3 layer0) {
                // 加权系数基于人眼对RGB通道的敏感度
                // return dot(color, float3(0.299, 0.587, 0.114));
                // return 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
                float gray = dot(layer0, float3(0.2126, 0.7152, 0.0722));
                return float3(gray, gray, gray);
                
            }
            float3 DT_PS_COLORING(float3 _layer0, float3 _layer1)
            {
                float gray = getLuminance(_layer0); //DT_GetGray
                float tmpmin = smoothstep(0.5, 0.0, gray);
                float3 tmpmax = smoothstep(0.5, 1.0, gray);
                // float m = max(_layer1.b,max(_layer1.r, _layer1.g)) * 2.0;
                float3 finalColor = lerp(gray * (_layer1 * 2.0), gray, (tmpmin + tmpmax )) ;
                return  saturate(finalColor); //_layer1 ;//  
            }
             
        // ==================================================================
        //
        // 单色 LIGHTEN
        //
        // ==================================================================
            
            float3 DT_PS_MONO_LIGHTEN(float3 layer0, float _value) 
            {  
                return lerp(layer0, DT_GetGray(layer0), _value);
            }
        // ==================================================================
        //
        // 单色反相 INVERT
        //
        // ==================================================================
            
            float3 DT_PS_MONO_INVERT(float3 layer0, float _value) {
                return abs(_value - layer0);
            }

        // ==================================================================
        //
        // 单色 通道转透明度
        //
        // ==================================================================
            float DT_PS_MONO_CHANLLEL_TO_ALPHA(float4 _Layer0, int mode) {
                int index = clamp(mode, 0, 4);
                if(index < 4){
                    float4 tmp = _Layer0 * DTOneChannelMask[index];
                    return tmp.r + tmp.g + tmp.b + tmp.a;
                }
                else{
                    float tmp = DT_GetGray(_Layer0.rgb) * _Layer0.a;
                    return tmp;
                }                
            }
    #endif //UNITY_SHADER_DT_COLORBLEND_UTIL_INCLUDED 

// ================================================================================================================================================ 
//
//
//
//
//
//
//
// UV模块
//
//
//
//
//
//
//
// ================================================================================================================================================  
    //
    //    变换过程优先级:   //    
    //        1.模型UV/屏幕UV
    //        2.矩阵变换(一次性的，旋转，缩放（翻转），偏移) 
    //        5.clamp限定0-1的UV
    //        3.极坐标      
    //        4.动态偏移UV
    //        6.序列帧 (如果有的话)
    //        7.扰动UV
    // ==================================================================
        // 需要用到的Properties面板变量
        // [Header(#### Properties)]
        // _####Tex ("#### Texture", 2D) = "white" {}
        // [Toggle]_####IsScene ("####'UV Is Scene", Float) = 0
        // [Toggle]_####IsPolar ("####'UV Is Polar", Float) = 0
        // [Toggle]_####IsClampX ("####'UV Is Clamp X", Float) = 0
        // [Toggle]_####IsClampY ("####'UV Is Clamp Y", Float) = 0
        // [Toggle]_####IsLocalX ("####'UV Is World X", Float) = 0
        // [Toggle]_####IsLocalY ("####'UV Is World Y", Float) = 0
        
        // _####Angle ("####'UV Angle", Float) = 0.0
        // [Enum(Val,0,Speed,1,C1.x,2,C1.y,3,C1.z,4,C1.w,5)]_####Umode ("####'UV U Offset Mode", Float) = 0
        // _####Uoffset ("####'UV U Offset", Float) = 0.0
        // [Enum(Val,0,Speed,1,C1.x,2,C1.y,3,C1.z,4,C1.w,5)]_####Vmode ("####'UV V Offset Mode", Float) = 0
        // _####Voffset ("####'UV V Offset", Float) = 0.0

        // [Toggle]_####IsDist ("####'Dist Is Dist", Float) = 0
        // _####DistX ("####'Dist X", Float) = 0
        // _####DistY ("####'Dist Y", Float) = 0

        // _####GridX ("####'Frame Grid X", Float) = 0
        // _####GridY ("####'Frame Grid Y", Float) = 0
        // [Toggle]_####IsAuto ("####'Frame Time Is Auto", Float) = 0
        // _####FrameTime ("####'Frame Time", Float) = 0.0 

        // float4 _####Tex_ST; 
        // int _####Umode; int _####Vmode; 
        // bool _####IsScene; bool _####IsPolar; bool _####IsClampX; bool _####IsClampY; bool _####IsLocalX; bool _####IsLocalY;            
        // int _####IsDist;float _####DistX; float _####DistY;
        // int _####GridX; int _####GridY; bool _####IsAuto;
        // // 可动画属性 Animatable Properties
        // float _####Angle; float _####Uoffset; float _####Voffset; float _####FrameTime;
    // ==================================================================
    #ifndef UNITY_SHADER_DT_UV_UTIL_INCLUDED  
    #define UNITY_SHADER_DT_UV_UTIL_INCLUDED
        // ==================================================================
        // 引用
        // ==================================================================
        //  #include "XXXXXX.hlsl"  

        // ============================================================================================================================================
        //
        //
        //
        //
        // 变换的矩阵
        //
        //
        //
        //
        // ============================================================================================================================================
            
            // ==================================================================
            // 常量
            // ==================================================================
                const float4x4 _DTDefMatr = float4x4
                (
                    1.0, 0.0, 0.0, 0.0,
                    0.0, 1.0, 0.0, 0.0,
                    0.0, 0.0, 1.0, 0.0,
                    0.0, 0.0, 0.0, 1.0
                );

                const float4x4 _DThalfMatr = float4x4
                (
                    0.5, 0.0, 0.0, 0.5,
                    0.0, 0.5, 0.0, 0.5,
                    0.0, 0.0, 1.0, 0.0,
                    0.0, 0.0, 0.0, 1.0
                );        
                const float4x4 _DTCenterMatr = float4x4
                (
                    2.0, 0.0, 0.0, -1.0,
                    0.0, 2.0, 0.0, -1.0,
                    0.0, 0.0, 1.0,  0.0,
                    0.0, 0.0, 0.0,  1.0
                );
            // ==================================================================
            // 函数
            // ==================================================================            
                float4x4 RotUVMatrix(float angle) // normalizedValue 0-360
                {
                    float normalizedValue = angle / 360.0; // 归一化角度值到 0 到 1
                    float radians = normalizedValue * 3.14159265359 * 2.0; // 角度转换为弧度
                    float cosv = cos(radians); // 计算余弦值
                    float sinv = sin(radians); // 计算正弦值
                    return float4x4
                    (
                        cosv, -sinv, 0.0, 0.0,
                        sinv,  cosv, 0.0, 0.0,
                        0.0,   0.0, 1.0, 0.0,
                        0.0,   0.0, 0.0, 1.0
                    );
                }
                float4x4 TilingAndOffsetUVMatrix(float4 _TilingOffset)
                {
                    return float4x4
                    (
                        _TilingOffset.x, 0.0f, 0.0f, -1.0 * _TilingOffset.z,
                        0.0f, _TilingOffset.y, 0.0f, -1.0 * _TilingOffset.w,
                        0.0f, 0.0f, 1.0f, 0.0f,
                        0.0f, 0.0f, 0.0f, 1.0f
                    );
                }
                //计算UV矩阵
                #if defined(DT_USE_OPTIMIZE)
                    //AI帮助合并了矩阵的计算中的常量、重复计算等。所以这个结果只能使用无法再做顺序改动
                    float4x4 CalcUVMatrix(float2 _Tiling, float2 Offset, float angle)
                    {
                        // 直接计算合并后的矩阵元素，避免矩阵乘法
                        float normalizedValue = angle / 360.0;
                        float radians = normalizedValue * 3.14159265359 * 2.0;
                        float cosv = cos(radians);
                        float sinv = sin(radians);
                        
                        // 一次性计算所有变换的组合效果                    
                        // 预计算重复使用的表达式
                        float2 cos_s = cosv * _Tiling;
                        float2 sin_s = sinv * _Tiling;                    
                        // 预计算偏移相关项 
                        float2 t2 = 2.0 * Offset;

                        float term1 = -cos_s.x + sin_s.y - t2.x * cos_s.x + t2.y * sin_s.y;
                        float term2 = -sin_s.x - cos_s.y + t2.x * sin_s.x + t2.y * cos_s.y;
                        
                        // 合并所有矩阵变换：_DThalfMatr * (rotMatr * tranMatr) * _DTCenterMatr
                        // 直接计算最终的矩阵元素
                        return float4x4(
                            cos_s.x, -sin_s.y, 0.0, 0.5 * term1 + 0.5,
                            sin_s.x, cos_s.y,  0.0, 0.5 * term2 + 0.5,
                            0.0, 0.0, 1.0, 0.0,
                            0.0, 0.0, 0.0, 1.0
                        );
                    }
                #else
                    float4x4 CalcUVMatrix(float2 _Tiling,float2 Offset,float angle)
                    {
                        float4x4 rotMatr =  RotUVMatrix(angle);
                        float4x4 tranMatr = TilingAndOffsetUVMatrix(float4(_Tiling, Offset));
                        float4x4 finalMatr = mul(rotMatr, tranMatr);
                        return mul(_DThalfMatr, mul(finalMatr, _DTCenterMatr));
                    }
                #endif
                // 极坐标计算
                float2 CalcPolarCoord(float2 _uv, float2 Center)
                {
                    const float2 delta = _uv - Center;
                    const float radius = length(delta) * 2.0;
                    const float angle = atan2(delta.x, delta.y) * DT_INV2PI;
                    // 不同以往的改动  重要改动
                    return float2(radius,angle);
                }
                // 计算屏幕坐标[顶点函数内的函数]
                float3 CalcSceneCoord_Vectex(float4 positionHCS)
                {
                    const float4 tmp = ComputeScreenPos(positionHCS);            
                    return float3(tmp.xy / DT_SAFE_VALUE(tmp.w),tmp.w);
                }

                
            // ==================================================================
            // 结构体
            // ================================================================== 
                struct MatrixResult
                {
                    float2 Tiling;
                    float2 Offset;
                    float Angle;
                    float2 CustomOffset; 
                    float2 IsWorld;
                };
            // ==================================================================
            // 初始化
            // ================================================================== 
                MatrixResult InitMatrixData(float4 _TilingOffset, float _Angle,float2 _CustomOffset,float2 _isWorld)
                {
                    MatrixResult m = (MatrixResult)0;
                    m.Tiling = _TilingOffset.xy;
                    m.Offset = _TilingOffset.zw * float2(1.0, -1.0);
                    m.CustomOffset =  _CustomOffset;
                    m.Angle = _Angle; 
                    m.IsWorld = _isWorld;
                    return m;
                }
            // ==================================================================
            // 调用 & 计算  
            // ==================================================================    
                float2 AppendUVMatrix(float4 _uv, MatrixResult _Result, bool _IsSceneUV, bool _IsPolar, bool _IsClampX, bool _IsClampY)
                {
                    //模型UV/屏幕UV
                    float2 uv = _IsSceneUV ? _uv.zw : _uv.xy;
                    uv = frac(uv + _Result.CustomOffset * _Result.IsWorld); 
                    //矩阵变换
                    float4x4 uvMatrix = CalcUVMatrix(_Result.Tiling, _Result.Offset, _Result.Angle);
                    uv = frac(mul(uvMatrix, float4(uv, 1.0, 1.0)).xy);
                    //极坐标
                    uv = _IsPolar ? CalcPolarCoord(uv, float2(0.5, 0.5)) : uv;
                    uv = frac(uv + _Result.CustomOffset * (1.0 - _Result.IsWorld)); 
                    
                    //clamp
                    uv.x = _IsClampX ? clamp(uv.x,0.0,1.0) : uv.x;
                    uv.y = _IsClampY ? clamp(uv.y,0.0,1.0) : uv.y;
                    return uv;
                }
        // ============================================================================================================================================
        //
        //
        //
        //
        // 扰动模块
        //
        //
        //
        //
        // ============================================================================================================================================
            // ==================================================================
            // 结构体
            // ================================================================== 
                struct DistortResult
                { 
                    float InputData; //从贴图输入的值 
                    float2 Factor; //扰动的控制值
                };
            // ==================================================================
            // 初始化
            // ================================================================== 
                DistortResult InitDistortResult(float _InputData, float2 _Factor)
                {
                    DistortResult d = (DistortResult)0;
                    d.InputData = _InputData;
                    d.Factor = _Factor * float2(-1.0, 1.0);
                    return d;
                }
            // ==================================================================
            // 调用 & 计算
            // ==================================================================
                //应用于 float
                void AppendDistortResultV1(DistortResult _Result,inout float _Value)
                {  
                    _Value = _Value * max( 1.0 , _Result.Factor.x * _Result.InputData); 
                }
                //应用于 float2
                void AppendDistortResultV2(DistortResult _Result,inout float2 _Value)
                {  
                    _Value = _Value + _Value * _Result.Factor * _Result.InputData;
                }
                //应用于 UV
                void AppendDistortResultUV(inout float2 _Value, DistortResult _Result)
                { 
                    _Value = _Value * 2.0 - 1.0;
                    _Value = _Value + _Value * _Result.Factor * _Result.InputData;
                    _Value = _Value * 0.5 + 0.5;  
                }
        // ============================================================================================================================================
        //
        //
        //
        //
        // 序列帧模块
        //
        //
        //
        //
        // ============================================================================================================================================
            // ==================================================================
            // 结构体
            // ================================================================== 
                struct DTFrameResult
                {
                    int IsOn; //是否开启 
                    float I_Value; //时间值

                    int GridX; //切片X
                    int GridY; //切片Y 
                };

                void SafeFrameResult(inout DTFrameResult d)
                {
                    d.GridX = max(d.GridX, 1); //切片X
                    d.GridY = max(d.GridY, 1); //切片Y
                }
            // ==================================================================
            // 初始化
            // ================================================================== 
                DTFrameResult InitFrameResult(int _FrameGridX, int _FrameGridY, float _FrameTime)
                {
                    DTFrameResult d = (DTFrameResult)0;
                    d.IsOn = (_FrameGridX + _FrameGridY) ; //是否开启
                    d.I_Value = _FrameTime; //时间值
                    d.GridX = _FrameGridX; //切片X
                    d.GridY = _FrameGridY; //切片Y
                    return d;
                }
            // ==================================================================
            // 调用 & 计算
            // ================================================================== 
                void AppendFrameResult(inout float2 _UV, DTFrameResult d)
                {
                    if(d.IsOn > 0.5)
                    {
                        SafeFrameResult(d);
                        float time = floor(d.I_Value);
                        float row = floor(time / d.GridX);
                        float column = time - row * d.GridX; 
                        float2 tiledUV = frac(_UV);
                        tiledUV.x = tiledUV.x / d.GridX + column / d.GridX;
                        tiledUV.y = tiledUV.y / d.GridY + (d.GridY - 1.0 - row) / d.GridY;
                        _UV = tiledUV;
                    }
                }
    #endif //UNITY_SHADER_DT_UV_UTIL_INCLUDED
   
// ======================================================================================================================================================================================================
//
//
//
//
//
//
//
// GROUND 地面裁切模拟
//
//
//
//
//
//
//
// ======================================================================================================================================================================================================
    #ifndef UNITY_SHADER_DT_GROUND_UTIL_INCLUDED    
    #define UNITY_SHADER_DT_GROUND_UTIL_INCLUDED
        // ==================================================================
        // 引用
        // ==================================================================
        //  #include "XXXXXX.hlsl" 
        // ==================================================================
        // 结构体
        // ================================================================== 

        // 输出的结果
        struct GroundResult
        {
            float Alpha;//DissolveValue; //溶解值
            float Edge; //溶解边缘
            float3 EdgeColor; //溶解边缘颜色
        };
        
        // ==================================================================
        // 计算  
        // ==================================================================
        GroundResult CalcGroundResult(float _IsOn, float _InputData, float _Factor)
        {
            GroundResult r = (GroundResult)0;
            r.Alpha = 1;
            r.Edge = 0; 
            r.EdgeColor = float3(0,0,0);
            if(_IsOn > 0.5) 
            {
                float clipH = _Factor;                              
                // 计算
                r.Alpha = smoothstep(clipH, clipH, _InputData);                            
            }                  
            return r;
        }
        GroundResult CalcGroundResult_S(float _IsOn, float _InputData, float _Factor,float _Soft)
        {
            GroundResult r = (GroundResult)0;
            r.Alpha = 1;
            r.Edge = 0; 
            r.EdgeColor = float3(0,0,0);
            if(_IsOn > 0.5) 
            {
                float clipH = _Factor;
                float _soft = max(0.0, _Soft);                
                // 计算
                r.Alpha = smoothstep(clipH, clipH + _soft, _InputData);                            
            }                  
            return r;
        }

        GroundResult CalcGroundResult_SW(float _IsOn, float _InputData, float _Factor,
            float _Soft, float _Wide, float _Widesoft,float4 EdgeColor)
        {
            GroundResult r = (GroundResult)0;
            r.Alpha = 1;
            r.Edge = 0; 
            r.EdgeColor = float3(0,0,0);
            if(_IsOn > 0.5) 
            {
                float clipH = _Factor;
                float _soft = max(0.0, _Soft);
                float _wide = _Wide;
                float _widesoft = max(0.0, _Widesoft);
                r.EdgeColor = EdgeColor.rgb * EdgeColor.a;
                // 计算
                r.Alpha = smoothstep(clipH, clipH + _soft, _InputData); 
                r.Edge = 1.0 - smoothstep(clipH + _wide, clipH + _wide + _widesoft, _InputData);                 
            }                  
            return r;
        }

        GroundResult CalcGroundResult_SWD(float _IsOn, float _InputData, float _Factor,  
            float _Soft, float _Wide, float _Widesoft,float4 EdgeColor,DistortResult _DistResult)
        {
            GroundResult r = (GroundResult)0;
            r.Alpha = 1;
            r.Edge = 0; 
            r.EdgeColor = float3(0,0,0);
            if(_IsOn > 0.5) 
            {
                float clipH = _Factor;
                float _soft = max(0.0, _Soft);
                float _wide = _Wide;
                float _widesoft = max(0.0, _Widesoft);                
                r.EdgeColor = EdgeColor.rgb * EdgeColor.a;
                // 计算
                r.Alpha = smoothstep(clipH, clipH + _soft, _InputData); 
                r.Edge = 1.0 - smoothstep(clipH + _wide, clipH + _wide + _widesoft, _InputData); 
 
                float2 tmpv = float2(r.Alpha,r.Edge); 
                AppendDistortResultV1(_DistResult,r.Alpha);
                AppendDistortResultV1(_DistResult,r.Edge);
                tmpv = saturate(tmpv);
                r.Alpha = tmpv.x;
                r.Edge = tmpv.y;
            }                  
            return r;
        }

        GroundResult CalcGroundResult_Base(float _IsOn, float _InputData, float _Factor,  
            float _Soft, float _Wide, float _Widesoft,float4 EdgeColor,DistortResult _DistResult)
        {
            GroundResult r = (GroundResult)0;
            r.Alpha = 1;
            r.Edge = 0; 
            r.EdgeColor = EdgeColor.rgb * EdgeColor.a;
            if(_IsOn > 0.5) 
            {
                float clipH = _Factor;
                float _soft = min(0.0, _Soft);
                float _wide = _Wide;
                float _widesoft = min(0.0, _Widesoft);
                // 计算
                r.Alpha = smoothstep(clipH, clipH + _soft, _InputData); 
                r.Edge = 1.0 - smoothstep(clipH + _wide, clipH + _wide + _widesoft, _InputData); 
 
                float2 tmpv = float2(r.Alpha,r.Edge); 
                AppendDistortResultV2(_DistResult,tmpv);
                tmpv = saturate(tmpv);
                r.Alpha = tmpv.x;
                r.Edge = tmpv.y;
            }                  
            return r;
        }
        //abort
        void ApplyGroundEffect_A(GroundResult result,inout float alpha)
        {
            alpha = alpha * result.Alpha;
        }
        void ApplyGroundEffect_AC_BLend(GroundResult result,inout float3 color,inout float alpha)
        {
            alpha = alpha * result.Alpha;
            color = lerp(color, result.EdgeColor, result.Edge); 
        }
        void ApplyGroundEffect_AC_Add(GroundResult result,inout float3 color,inout float alpha)
        {
            alpha = alpha * result.Alpha; 
            color += result.EdgeColor * result.Edge;
        }
    
    #endif //UNITY_SHADER_DT_GROUND_UTIL_INCLUDED 
// ======================================================================================================================================================================================================
//
//
//
//
//
//
//
// 
//
//
//
//
//
//
//
// ======================================================================================================================================================================================================
    #include "DTmaskUtil.hlsl"
    // UNITY_SHADER_DT_MASK_UTIL_INCLUDED
// ======================================================================================================================================================================================================

// #include "DTdissUtil.hlsl"
// UNITY_SHADER_DT_DISSOLVE_UTIL_INCLUDED
// ============================================================================================================================================
//
//
//
//
// 溶解模块
//
//
//
//
// ============================================================================================================================================
#ifndef UNITY_SHADER_DT_DISSOLVE_UTIL_INCLUDED
#define UNITY_SHADER_DT_DISSOLVE_UTIL_INCLUDED
        // ==================================================================
        // 引用
        // ==================================================================
        //  #include "XXXXXX.hlsl"
        // ==================================================================
        // 溶解函数
        //     溶解:特效溶解模块的所有功能
        //     结构体: DissolveResult
        //     函数:
        //          基础溶解
        //          DissolveResult dissResult = CalcDissolveResult(bool ison, float data, float _Factor);、        
        //          可调溶解边
        //          DissolveResult dissResult = CalcDissolveResult_S(bool ison, float data, float _Factor, float _Soft);
        //          可调溶解边+溶解边扭曲
        //          DissolveResult dissResult = CalcDissolveResult_SD(bool ison, float data, float _Factor, float _Soft
        //                                                      DistDistortResult _DistResult);
        //          可调溶解边+溶解描边
        //          DissolveResult dissResult = CalcDissolveResult_SW(bool ison, float data, float _Factor, float _Soft, 
        //                                                      float _Wide, float4 _EdgeColor);
        //          可调溶解边+溶解描边+溶解边扭曲
        //          DissolveResult dissResult = CalcDissolveResult_SWD(bool ison, float data, float _Factor, float _Soft, 
        //                                                      float _Wide, float4 _EdgeColor, DistDistortResult _DistResult);
        //          应用
        //          ApplyDissolveEffect(DissolveResult _Result, bool isOn, inout float3 _FColor, inout float _FAlpha)
        // ==================================================================
        #ifdef DT_USE_OPTIMIZE
            #define DT_USE_SELF_DISS //使用自己的溶解 
        #endif

        // ================================================================== 
        // 结构体  
        // ================================================================== 

        // 输出的结果
        struct DissolveResult
        {
            float Alpha;//DissolveValue; //溶解值
            float Edge; //溶解边缘
            float3 EdgeColor; //溶解边缘颜色
        };
 
        // ==================================================================
        // 计算
        //     调用这个函数，就可以得到溶解的结果
        // ==================================================================
        DissolveResult CalcDissolveResult(float _isOn, float _InputData,float _Factor)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            { 
                float finalAlpha = 1;
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0; //把贴图色从0-1 => 1-2
                float _factor = saturate(_Factor) * 2.0 ; //溶解因子 0-1 => 0 - 2
                Outresult.Alpha = saturate(_inputData - _factor);
            }
            return Outresult;
        } 

        DissolveResult CalcDissolveResult_S(float _isOn, float _InputData, float _Factor,float _Soft)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {
                float finalAlpha = 1;
                //把贴图色从0-1 => 1-2
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0;
                //羽化因子    
                float _soft = clamp(_Soft, 0.01, 0.99);
                //溶解因子 0-1 => 0 - 2    
                float _factor = saturate(_Factor) ;  
                _factor *= 2.0 - _soft; 
                float tmpV = _inputData - _factor; //基础溶解
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue            
                Outresult.Alpha = saturate(finalAlpha); 
            }
            return Outresult;
        }

        DissolveResult CalcDissolveResult_SD(float _isOn, float _InputData, float _Factor,float _Soft,DistortResult _DistResult)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {
                float finalAlpha = 1;
                //把贴图色从0-1 => 1-2
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0;
                //羽化因子    
                float _soft = clamp(_Soft, 0.01, 0.99);
                //溶解因子 0-1 => 0 - 2    
                float _factor = saturate(_Factor) ;  
                _factor *= 2.0 - _soft; 
                float tmpV = _inputData - _factor; //基础溶解
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue
                AppendDistortResultV1(_DistResult, /*inout*/finalAlpha);         
                Outresult.Alpha = saturate(finalAlpha); 
            }
            return Outresult;
        }

        DissolveResult CalcDissolveResult_SW(float _isOn, float _InputData, float _Factor,
            float _Soft, float _Wide, float4 _EdgeColor)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {                 
                float finalAlpha = 1;
                float finalEdge = 0;
                
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0; //把贴图色从0-1 => 1-2
                
                float _factor/*Input*/ = _Factor ; //溶解因子 0-1 => 0 - 2 => 0 - -2【规避减法】  

                
                float _soft = clamp(_Soft, 0.001, 0.999);
                float _wide = saturate(_Wide);              
                    
                #if defined(DT_USE_SELF_DISS) 
                    _factor = dt_Ramp_float(_factor, 0.0, 1.0, -_wide, 1.0);
                    _factor *= 2.0 - _soft;
                #else
                    _factor *= 2.0;
                #endif

                float tmpV = _inputData - _factor; //基础溶解
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue

                #if defined(DT_USE_SELF_DISS)
                    finalEdge = smoothstep(_soft, 1.0, tmpV - _wide);// * step(0.000001, _wide); //edge
                    finalEdge = _wide > 0.000001 ? finalEdge : 1;
                #else
                    _wide = clamp(_Wide, 0.001, 0.999); 
                    finalEdge = smoothstep(_wide - _soft * 0.5, _wide, finalAlpha);
                #endif
                finalEdge = 1.0 - finalEdge;

                Outresult.Alpha = saturate(finalAlpha);
                Outresult.Edge = saturate(finalEdge);
                Outresult.EdgeColor = _EdgeColor.rgb * _EdgeColor.a;            
            }
            return Outresult;
        }

        DissolveResult CalcDissolveResult_SWD(float _isOn, float _InputData, 
            float _Factor,float _Soft, float _Wide, float4 _EdgeColor,
            DistortResult _DistResult) 
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {            
                Outresult.EdgeColor = _EdgeColor.rgb * _EdgeColor.a;

                float finalAlpha = 1;
                float finalEdge = 0;
                
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0; //把贴图色从0-1 => 1-2
                float _factor/*Input*/ = _Factor ; //溶解因子 0-1 => 0 - 2 => 0 - -2【规避减法】  

                
                float _soft = clamp(_Soft, 0.001, 0.999);
                float _wide = saturate(_Wide);              
                    
                #if defined(DT_USE_SELF_DISS) 
                    _factor = dt_Ramp_float(_factor, 0.0, 1.0, -_wide, 1.0);
                    _factor *= 2.0 - _soft;
                #else            
                    _factor *= 2.0;
                #endif

                float tmpV = _inputData - _factor; //基础溶解
                //finalAlpha = _inputData - _factor;
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue 

                #if defined(DT_USE_SELF_DISS)
                    finalEdge = smoothstep(_soft, 1.0, tmpV - _wide);// * step(0.000001, _wide); //edge
                    finalEdge = _wide > 0.000001 ? finalEdge : 1;
                #else
                    _wide = clamp(_Wide,0.001, 0.999);
                    finalEdge = smoothstep(_wide - _soft * 0.5, _wide, finalAlpha);
                #endif
                finalEdge = 1.0 - finalEdge;

                // 扰动
                AppendDistortResultV1(_DistResult, /*inout*/finalAlpha);
                // AppendDistortResultV1(_DistResult, /*inout*/finalEdge);

                //此处需要限定到0-1，因为这里其实在计算的还是颜色，不可控的溢出是不理智的。
                //下面赋值时会 saturate，所以这里省略
                Outresult.Alpha = saturate(finalAlpha);
                Outresult.Edge = saturate(finalEdge);
            } 
            return Outresult;
        }

        DissolveResult CalcDissolveResultBase(float _isOn, float _InputData, 
            float _Factor,float _Soft, float _Wide, float4 finalEdgeColor,
            float _DistResult, float _DistFactor)
        {
            DissolveResult Outresult = (DissolveResult)0;
            Outresult.Alpha = 1;
            Outresult.Edge = 0;
            Outresult.EdgeColor = float3(0,0,0);
            if(_isOn > 0.5)
            {            
                Outresult.EdgeColor = finalEdgeColor.rgb * finalEdgeColor.a;

                float finalAlpha = 1;
                float finalEdge = 0;
                
                float _inputData/*Data In Val*/ = saturate(_InputData) + 1.0; //把贴图色从0-1 => 1-2
                float _factor/*Input*/ = _Factor ; //溶解因子 0-1 => 0 - 2 => 0 - -2【规避减法】  

                
                float _soft = clamp(_Soft, 0.01, 0.99);
                float _wide = saturate(_Wide);              
                    
                #if defined(DT_USE_SELF_DISS) 
                    _factor = dt_Ramp_float(_factor, 0.0, 1.0, -_wide, 1.0);
                    _factor *= 2.0 - _soft;
                #else            
                    _factor *= 2.0;
                #endif

                float tmpV = _inputData - _factor; //基础溶解
                //finalAlpha = _inputData - _factor;
                finalAlpha = smoothstep(_soft, 1.0, tmpV); //softvalue 

                #if defined(DT_USE_SELF_DISS)
                    finalEdge = smoothstep(_soft, 1.0, tmpV - _wide);// * step(0.000001, _wide); //edge
                    finalEdge = _wide > 0.000001 ? finalEdge : 1;
                #else
                    _wide = clamp(_Wide,0.01, 0.99); 
                    finalEdge = smoothstep(_wide - _soft * 0.5, _wide, finalAlpha);
                #endif
                finalEdge = 1.0 - finalEdge;

                // 扰动
                DistortResult dstR = InitDistortResult(_DistResult, _DistFactor);
                AppendDistortResultV1(dstR, finalAlpha);

                //此处需要限定到0-1，因为这里其实在计算的还是颜色，不可控的溢出是不理智的。
                //下面赋值时会 saturate，所以这里省略
                Outresult.Alpha = saturate(finalAlpha);
                Outresult.Edge = saturate(finalEdge);
            } 
            return Outresult;
        }
        // ==================================================================
        // 调用
        //     color: 最终的颜色
        //     alpha: 最终的透明度
        //     调用这个函数，就可以得到溶解的结果
        // ==================================================================
        void ApplyDissolveEffect(float _isOn, DissolveResult result, inout float3 color,inout float alpha)
        {
            // UNITY_BRANCH
            if(_isOn > 0.5)
            {
                color = lerp(color, result.EdgeColor, result.Edge); 
                alpha *= result.Alpha;
                //小于0的颜色是不可控的。无特殊要求不允许颜色小于 0 
                color = max(0.0, color);
                //小于0或大于1的透明是不可控的。无特殊要求不允许透明溢出[0-1]的范围 
                alpha = saturate(alpha);
            }
        }
#endif // UNITY_SHADER_DT_DISSOLVE_UTIL_INCLUDED
// ======================================================================================================================================================================================================

// #include "DTFNLUtil.hlsl"
// UNITY_SHADER_DT_FNL_UTIL_INCLUDED

// ============================================================================================================================================
//
//
//
//
// FNL 菲尼尔模块
//
//
//
//
// ============================================================================================================================================
#ifndef UNITY_SHADER_DT_FNL_UTIL_INCLUDED  
#define UNITY_SHADER_DT_FNL_UTIL_INCLUDED
    // ==================================================================
    // 引用
    // ==================================================================
    //  #include "XXXXXX.hlsl"

    // ==================================================================
    // 私有函数
    // ==================================================================
    bool DTIsPerspectiveProjection()
    {
        return (unity_OrthoParams.w == 0);
    }
    void GetDot_N2V(float3 normalWS, float3 positionWS, inout float fnlvalue)
    { 
        if(DTIsPerspectiveProjection())//当是透视相机时
        {
        #if defined(DT_URP_MODE)
            float3 worldViewDir = GetWorldSpaceNormalizeViewDir(positionWS.xyz);
        #else
            float3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz - positionWS.xyz);
        #endif
            fnlvalue = dot(normalWS.xyz, worldViewDir.xyz); 
        }
        else
        {
            float3 normalView = mul((float3x3)UNITY_MATRIX_V, normalWS).xyz;
            fnlvalue = clamp(normalView.z, -1.0, 1.0);             
        }
    }
    float DTOptimizeFnlSoft(float fnlvalue, float _Soft,float _Scale, float _Wide = 0.0)
    {
        #ifdef DT_USE_OPTIMIZE
            //Safe 安全约束
            float white = clamp(0.001, 1.0, _Wide);
            float black = clamp(0.0, 0.999, _Soft);// min(wide - 0.01,_Soft);
            black = min(white - 0.001 , black); 
            //求值
            float v = smoothstep( black, white, fnlvalue);
        #else
            float v = pow(fnlvalue, _Soft * 10.0) ; 
        #endif
        return v * _Scale;
    }
    float DTFNL01(float fnlvalue)
    {
        return saturate(fnlvalue * 0.5 + 0.5);
    }
    float DTFNL010(float fnlvalue)
    {
        return saturate(1.0 - abs(fnlvalue));
    }
    // ==================================================================
    // 结构体
    // ==================================================================
   
    struct FresnelResult
    {
        float3 color;
        float value;
        float colBlend; // 0:add,1: mul
        float alpBlend; // 0:不影响，1：影响
    };
    FresnelResult initFresnelResult(float blend, float alpblend)
    {
        FresnelResult result = (FresnelResult)0;
        //安全计算
        result.colBlend = blend > 0 ? 1.0 : 0.0;
        result.alpBlend = alpblend > 0 ? 1.0 : 0.0;
        //安全计算
        result.alpBlend = 1.0 - result.alpBlend;
        result.color = float3(result.colBlend,result.colBlend,result.colBlend);            
        result.value = alpblend;
        return result;
    }    
    // ==================================================================
    // 计算函数
    // ==================================================================
    //0-1[反面到正面]
    FresnelResult CalcFresnelResult_Tex(int _IsOn, float3 _NormalWS,float3 _PositionWS, 
        float _Scale, float _Soft, float _ColBlend, float _Alpblend, float _Wide, float4 _FNLColor, float _IsFilp,sampler2D tex,float2 _uv)     
    {
        FresnelResult Result = initFresnelResult(_ColBlend,_Alpblend);
        if(_IsOn > 0.00001)
        {
            Result.color = _FNLColor.rgb * _FNLColor.a;
            float fnlvalue = 0;
            GetDot_N2V(_NormalWS,  _PositionWS, fnlvalue);
            fnlvalue =  DTFNL01(fnlvalue);
            fnlvalue = smoothstep( _Soft, 1.0, fnlvalue) ; 
            float2 _fnlUV = float2(fnlvalue, _uv.y );// + frac(float2(0.0,0.0) * float2(_Time.y,_Time.y));
            //从贴图获取 贴图取横向的U
            float4 texvalue = tex2D(tex, _fnlUV);
            texvalue = abs(_IsFilp - texvalue);
            Result.value = texvalue.a;
            Result.color = texvalue.rgb * Result.color;
        }
        return Result;
    }

    //0-1-0[反面到正面]
    FresnelResult CalcFresnelResult_F010(int _IsOn, float3 _NormalWS,float3 _PositionWS, 
        float _Scale, float _Soft, float _ColBlend, float _Alpblend, float _Wide, float4 _FNLColor, float _IsFilp)
    {
        FresnelResult Result = initFresnelResult(_ColBlend,_Alpblend); 
        if(_IsOn > 0.00001)
        {
            float _scale = _Scale;
            float _soft = _Soft;
            Result.color = _FNLColor.rgb * _FNLColor.a;
            float fnlvalue = 0;
            GetDot_N2V(_NormalWS, _PositionWS, fnlvalue);            
            //是否反相 
            fnlvalue = abs(_IsFilp - fnlvalue);
            //决定使用哪种显示模式，FULL：0->1 [反面到正面]，0-1-0[反面到正面]
            fnlvalue = DTFNL010(fnlvalue);
            //计算调节
            Result.value = DTOptimizeFnlSoft(fnlvalue,_Soft,_Scale, _Wide); 
        }
        return Result;
    }
    //0->1 [反面到正面]
    FresnelResult CalcFresnelResult_F01(int _IsOn, float3 _NormalWS,float3 _PositionWS, 
        float _Scale, float _Soft, float _ColBlend, float _Alpblend, float _Wide,float4 _FNLColor, float _IsFilp)
    {
        FresnelResult Result = initFresnelResult(_ColBlend,_Alpblend); 
        if(_IsOn > 0.00001)
        {
            float _scale = _Scale;
            float _soft = _Soft;
            Result.color = _FNLColor.rgb * _FNLColor.a;
            float fnlvalue = 0;
            GetDot_N2V(_NormalWS, _PositionWS, fnlvalue);

            //是否反相 
            fnlvalue = abs(_IsFilp -  fnlvalue);
            fnlvalue = saturate(fnlvalue * 0.5 + 0.5);
            fnlvalue = 1.0 - fnlvalue;
            //计算调节
            Result.value = DTOptimizeFnlSoft(fnlvalue, _Soft,_Scale, _Wide);
        }
        return Result;
    }


    FresnelResult CalcFresnelResult_Base(int _IsOn, float3 _NormalWS,float3 _PositionWS, 
        float _Scale, float _Soft, float _ColBlend, float _Alpblend,float4 _FNLColor, float _IsFilp, float _IsFull)
    {
        FresnelResult Result = initFresnelResult(_ColBlend,_Alpblend);
        if(_IsOn > 0.00001)
        {
            float _scale = _Scale;
            float _soft = _Soft;
            Result.color = _FNLColor.rgb * _FNLColor.a;
            float fnlvalue = 0;
            GetDot_N2V(_NormalWS, _PositionWS, fnlvalue);            
            //是否反相 
            fnlvalue = abs(_IsFilp - fnlvalue);            
            //决定使用哪种显示模式，FULL：0->1 [反面到正面]，0-1-0[反面到正面]
            float _IsFull = 0.0;
            fnlvalue = lerp(abs(fnlvalue),fnlvalue * 0.5 + 0.5, _IsFull);
            fnlvalue = saturate(1.0 - fnlvalue);

            //计算调节
            Result.value = DTOptimizeFnlSoft(fnlvalue,_Soft,_Scale); 
        }
        return Result;
    }
    // ==================================================================
    // 调用函数
    // ==================================================================
    void ApplyFresnelEffect(FresnelResult result, inout float3 color,inout float alpha)
    { 
        float3 c = lerp(color + result.color, color * result.color, result.colBlend);
        color = lerp(color, c, result.value);
        //小于0的颜色是不可控的。无特殊要求不允许颜色小于 0 
        color = max(0.0, color);
        //isAlp 不能小于0
        //isAlp = max(0.0, isAlp);
        alpha *= saturate(result.alpBlend + result.value); 
        //小于0或大于1的透明是不可控的。无特殊要求不允许透明溢出[0-1]的范围 
        alpha = max(0.0, alpha);
    }
#endif //UNITY_SHADER_DT_FNL_UTIL_INCLUDED

// ======================================================================================================================================================================================================
//
//
//
//
//
//
//
// 自定义的重要公共内容
//
//
//
//
//
//
//
// ======================================================================================================================================================================================================
    #ifndef UNITY_SHADER_DT_FXSHADER_UTIL_INCLUDED  
    #define UNITY_SHADER_DT_FXSHADER_UTIL_INCLUDED
        //--------------------------------------------
        struct DTVFX_appdata
        {
            float4 vertex         : POSITION;
            float4 vertexColor    : COLOR;
            float4 normal         : NORMAL;
            float4 texcoord0      : TEXCOORD0; // xy:UV;zw:particleCustom1.xy      |        
            float4 texcoord1      : TEXCOORD1; // xy:particleCustom1.zw zw:particleCustom2.xy  |
            float4 texcoord2      : TEXCOORD2; // xy:particleCustom2.zw   |        
            UNITY_VERTEX_INPUT_INSTANCE_ID
        };
        struct DTVFX_v2f
        {
            float4 vertex       : SV_POSITION;     //
            float4 vertexColor  : COLOR;           //
            float4 uv           : TEXCOORD0;       //#0 xy:uv0,zw:屏幕uv
            float4 positionWS   : TEXCOORD1;       //#1 xyz:positionWS,w:ScreenPos.w
            float4 normalWS     : TEXCOORD2;       //#2 xyz:normalWS,w:0
            float4 Custom1      : TEXCOORD3;       //#3 
            float4 Custom2      : TEXCOORD4;       //#4 
            // float4 ####         : TEXCOORD5;    //#5
            // float4 ####         : TEXCOORD6;    //#6
            #ifdef UNITY_UI_CLIP_RECT
                float4 mask     : TEXCOORD7;
            #endif
            UNITY_VERTEX_INPUT_INSTANCE_ID
            UNITY_VERTEX_OUTPUT_STEREO
        };
        // ==================================================================
        //
        // 顶点函数
        //
        // ==================================================================
            DTVFX_v2f VFXvert(DTVFX_appdata v)
            {
                //-------------------------------------------------------------
                //初始化
                //-------------------------------------------------------------
                DTVFX_v2f o = (DTVFX_v2f)0;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_TRANSFER_INSTANCE_ID(v, o);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                //-------------------------------------------------------------
                //计算
                //-------------------------------------------------------------
                    float3 posOS =  v.vertex.xyz; 
                    #if defined(DT_USE_DIST)
                        float3 posWS    = TransformObjectToWorld(posOS);
                        float4 posHCS   = TransformWorldToHClip(posWS); 
                        float3 normalWS = TransformObjectToWorldNormal(v.normal.xyz, true);                
                    #else                
                        float3 posWS    = mul(unity_ObjectToWorld, float4(posOS, 1.0)).xyz;
                        float4 posHCS   = UnityObjectToClipPos(posOS);
                        float3 normalWS = UnityObjectToWorldNormal(v.normal.xyz);
                    #endif
                    float4 screentmp = ComputeScreenPos(posHCS); 
                    float2 screenUV = screentmp.xy / DT_SAFE_VALUE(screentmp.w);//
                    float4 fullUV = float4(v.texcoord0.xy, screenUV.xy);

                    #ifdef UNITY_UI_CLIP_RECT
                        float2 pixelSize = posHCS.w;
                        pixelSize /= float2(1.0, 1.0) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy));
                        float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
                        float2 maskUV = (posOS.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy);
                        float4 clipmask = float4(posOS.xy * 2.0 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * float2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy)));
                    #endif
                //-------------------------------------------------------------
                //赋值开始
                //-------------------------------------------------------------
                    o.vertex = posHCS;
                    o.uv = fullUV;
                    o.vertexColor = v.vertexColor; 
                    o.positionWS = float4(posWS.x,posWS.y, posWS.z, screentmp.w);
                    o.normalWS = float4(normalWS.x,normalWS.y,normalWS.z, 0);
                    o.Custom1 = float4(v.texcoord0.zw,v.texcoord1.xy);
                    o.Custom2 = float4(v.texcoord1.zw,v.texcoord2.xy); 
                    #ifdef UNITY_UI_CLIP_RECT
                        o.mask = clipmask;
                    #endif
                return o;     
            }
    #endif //UNITY_SHADER_DT_FXSHADER_UTIL_INCLUDED
#endif //UNITY_SHADER_DT_EFFECT_TOOLS_UTIL_INCLUDED